﻿using System;
using System.Linq;
using System.Threading;
using Ibp.Service.Entity.ODAEntity;
using OdaOperation.Core.Parameters;
using OdaOperation.Core.Parameters.Base;
using OdaOperation.Extends;
using OdaOperation.Model;
using Teigha.Core;
using Teigha.TD;

namespace OdaOperation.Core.Creators
{
    public class TableLabelCreator : BaseCreator, IReferenceCreator, ISetParameter<TableLabelCreator, TableLabelParameter>
    {
        private TableLabelParameter m_parameter; // 表格标签参数对象

        /// <summary>
        /// 构造函数，接受一个 OdDbDatabase 对象作为参数
        /// </summary>
        /// <param name="pDb"></param>
        public TableLabelCreator(OdDbDatabase pDb)
            : base(pDb)
        {
        }

        /// <summary>
        /// 构造函数，接受 OdDbDatabase、图层名、表格尺寸等参数
        /// </summary>
        /// <param name="pDb"></param>
        /// <param name="layerName"></param>
        /// <param name="tableSize"></param>
        /// <param name="angle"></param>
        /// <param name="length1"></param>
        /// <param name="length2"></param>
        /// <param name="fontSize"></param>
        /// <param name="font"></param>
        public TableLabelCreator(OdDbDatabase pDb, string layerName, TableSize tableSize, double angle = Math.PI / 4.0, double length1 = 40.0, double length2 = 20.0, double fontSize = 3.75, string font = "F-HZTXT")
            : base(pDb, layerName)
        {
            // 初始化表格标签参数对象
            m_parameter = new TableLabelParameter
            {
                LayerName = layerName,
                TableSize = tableSize,
                Angle = angle,
                Length1 = length1,
                Length2 = length2,
                FontStyle = font,
                FontSize = fontSize
            };
            m_layerName = m_parameter.LayerName; // 设置图层名
        }

        /// <summary>
        /// 创建表格标签，接受表格数据和块名作为参数
        /// </summary>
        /// <param name="tables"></param>
        /// <param name="blockName"></param>
        /// <returns></returns>
        public TableLabelCreator Create(TableData tables, string blockName = null)
        {
            // 如果传入的块名不为空且与参数中的块名不同，则更新参数中的块名
            if (!string.IsNullOrWhiteSpace(blockName) && blockName != m_parameter.BlockName)
            {
                m_parameter.BlockName = blockName;
            }

            m_parameter.TableData = tables; // 设置表格数据
            Create(); // 调用 Create 方法创建表格标签
            return this; // 返回当前对象
        }

        /// <summary>
        /// 创建块参照，接受位置、缩放、旋转等参数
        /// </summary>
        /// <param name="location"></param>
        /// <param name="odGeScale"></param>
        /// <param name="rotating"></param>
        /// <param name="mirrorPlane"></param>
        public void CreateBlockReference(DPoint location, OdGeScale3d odGeScale = null, double rotating = 0.0, OdGePlane mirrorPlane = null)
        {
            new BlockReferenceCreator(m_database, m_parameter.BlockName, m_layerName).Create(new OdGePoint3d(location.X, location.Y, location.Z), odGeScale, rotating, mirrorPlane);
        }

        /// <summary>
        /// 创建块参照，接受位置、缩放、旋转等参数
        /// </summary>
        /// <param name="location"></param>
        /// <param name="odGeScale"></param>
        /// <param name="rotating"></param>
        /// <param name="mirrorPlane"></param>
        /// <param name="paramters"></param>
        public void CreateBlockReference(OdGePoint3d location, OdGeScale3d odGeScale = null, double rotating = 0.0, OdGePlane mirrorPlane = null, ParameterSet paramters = null)
        {
            new BlockReferenceCreator(m_database, m_parameter.BlockName, m_layerName).Create(location, odGeScale, rotating, mirrorPlane, paramters);
        }

        /// <summary>
        /// 创建块参照，接受参照参数对象作为参数
        /// </summary>
        /// <param name="paramter"></param>
        public void CreateBlockReference(ReferenceParameter paramter)
        {
            new BlockReferenceCreator(m_database, m_parameter.BlockName, paramter.LayerName).Create(paramter.Location.ToGePoint3D(), paramter.Scale, paramter.Rotating, paramter.MirrorPlane, paramter.Parameters);
        }

        /// <summary>
        /// 创建块参照，接受图层名、位置、缩放、旋转等参数
        /// </summary>
        /// <param name="layerName"></param>
        /// <param name="location"></param>
        /// <param name="odGeScale"></param>
        /// <param name="rotating"></param>
        /// <param name="mirrorPlane"></param>
        /// <param name="paramters"></param>
        public void CreateBlockReference(string layerName, DPoint location, OdGeScale3d odGeScale = null, double rotating = 0.0, OdGePlane mirrorPlane = null, ParameterSet paramters = null)
        {
            new BlockReferenceCreator(m_database, m_parameter.BlockName, layerName).Create(location.ToGePoint3D(), odGeScale, rotating, mirrorPlane, paramters);
        }

        /// <summary>
        /// 设置表格标签参数
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public TableLabelCreator SetParameter(TableLabelParameter parameter)
        {
            parameter.Check(); // 检查参数的有效性
            m_parameter = parameter; // 设置参数对象
            m_layerName = m_parameter.LayerName; // 更新图层名
            return this; // 返回当前对象
        }

        /// <summary>
        /// 创建表格标签
        /// </summary>
        /// <returns></returns>
        internal TableLabelCreator Create()
        {
            m_parameter.Check(); // 检查参数的有效性
            m_parameter.TableSize.InitFromTable(m_parameter.TableData); // 根据表格数据初始化表格尺寸
            MemoryTransaction value = MemoryManager.GetMemoryManager().StartTransaction(Thread.CurrentThread.ManagedThreadId); // 开始内存事务
            try
            {
                // 获取数据库中的文本样式表
                OdDbTextStyleTable odDbTextStyleTable = m_database.getTextStyleTableId().openObject() as OdDbTextStyleTable;
                // 初始化字体样式
                OdDbObjectId textStyle = TextStyleCreator.InitDefaultsFont(m_database);
                // 获取数据库中的块表
                OdDbBlockTable odDbBlockTable = m_database.getBlockTableId().openObject() as OdDbBlockTable;
                // 初始化一些变量
                OdGePoint3d odGePoint3d = new OdGePoint3d();
                OdGePoint3d odGePoint3d2 = new OdGePoint3d(m_parameter.Length1, 0.0, 0.0);
                odGePoint3d2.rotateBy(m_parameter.Angle, new OdGeVector3d(0.0, 0.0, 1.0), odGePoint3d);
                OdGePoint3d odGePoint3d3 = new OdGePoint3d(odGePoint3d2).Add(new OdGeVector3d(m_parameter.Length2, 0.0, 0.0));
                TableSize tableSize = m_parameter.TableSize;
                double num = m_parameter.TableSize.Cols.Sum();
                double num2 = m_parameter.TableSize.Rows.Sum();
                OdGePoint3d odGePoint3d4 = new OdGePoint3d(odGePoint3d3.x, odGePoint3d3.y - num2 * 0.5, 0.0);
                OdGeVector3d xAxis = new OdGeVector3d(1.0, 0.0, 0.0);
                OdGeVector3d yAxis = new OdGeVector3d(0.0, 1.0, 0.0);
                OdDbBlockTableRecord odDbBlockTableRecord;

                // 检查是否存在指定名称的块表记录
                if (odDbBlockTable.has(m_parameter.BlockName))
                {
                    // 如果存在，则获取对应的块表记录对象
                    odDbBlockTableRecord = odDbBlockTable.getAt(m_parameter.BlockName, OpenMode.kForWrite) as OdDbBlockTableRecord;
                }
                else
                {
                    // 如果不存在，则创建新的块表记录对象
                    odDbBlockTableRecord = OdDbBlockTableRecord.createObject();
                    odDbBlockTableRecord.setName(m_parameter.BlockName);
                    odDbBlockTable.upgradeOpen();
                    odDbBlockTable.add(odDbBlockTableRecord);
                    odDbBlockTable.downgradeOpen();
                }

                m_blockTableId = odDbBlockTableRecord.objectId(); // 设置块表记录的对象 ID
                GridCreator gridCreator = new GridCreator(m_database, m_blockTableId, m_layerName); // 创建网格创建器对象
                LineCreator lineCreator = new LineCreator(m_database, m_blockTableId, m_layerName); // 创建线条创建器对象
                TableItemCreator tableItemCreator = new TableItemCreator(m_database, m_blockTableId, m_layerName, textStyle, odGePoint3d4, xAxis, yAxis, m_parameter.FontSize); // 创建表格项创建器对象
                gridCreator.CreateGrid(m_parameter.TableSize, odGePoint3d4, xAxis, yAxis); // 创建网格
                lineCreator.CreateLine(odGePoint3d, odGePoint3d2); // 创建线条
                lineCreator.CreateLine(odGePoint3d2, odGePoint3d3); // 创建线条

                // 遍历表格数据，创建表格项
                double num3 = 0.0;
                double num4 = 0.0;
                double num5 = 0.0;
                double bottom = 0.0;
                TableSize tableSize2 = m_parameter.TableSize;
                TableData tableData = m_parameter.TableData;
                for (int num6 = tableSize2.Rows.Count - 1; num6 >= 0; num6--)
                {
                    num5 += tableSize2.Rows[num6];
                    num4 = (num3 = 0.0);
                    for (int i = 0; i < tableSize2.Cols.Count; i++)
                    {
                        num4 += tableSize2.Cols[i];
                        TableItem item = tableData[num6][i];
                        tableItemCreator.Create(item, num3, num4, num5, bottom);
                        num3 = num4;
                    }

                    bottom = num5;
                }

                return this; // 返回当前对象
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                MemoryManager.GetMemoryManager().StopTransaction(value); // 停止内存事务
            }
        }
    }

}